﻿using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using System;
using Random = UnityEngine.Random;

namespace CGF
{
    /// <summary>
    /// 播放背景音乐专用
    /// </summary>
    public class MusicPlayer : ComponentBase, IAwake, IUpdate, IDestroy
    {
        public static Action<bool> onEnableChange;

        private static List<MusicPlayer> allMusicSources = new List<MusicPlayer>();

        /// <summary>
        /// 控制所有Music
        /// </summary>
        public static bool IsEnable
        {
            get { return PlayerPrefs.GetInt("MusicIsEnable", 1) == 1; }
            set
            {
                for (int i = 0; i < allMusicSources.Count; i++)
                {
                    allMusicSources[i].OnEnable(value);
                }
                onEnableChange?.Invoke(value);
                PlayerPrefs.SetInt("MusicIsEnable", value ? 1 : 0);
            }
        }

        /// <summary>
        /// 控制所有Music
        /// </summary>
        public static float Volume
        {
            get { return PlayerPrefs.GetFloat("MusicVolume", 1); }
            set
            {
                for (int i = 0; i < allMusicSources.Count; i++)
                {
                    allMusicSources[i].audioSource.volume = allMusicSources[i].volume * value;
                }
                PlayerPrefs.SetFloat("MusicVolume", value);
            }
        }


        private AudioSource audioSource;
        private float volume;
        private bool loop;
        private AudioClip[] clips;
        private int currClipIndex;
        private bool randomNext;
        private bool canListenPlayEnd;

        public void Awake()
        {
            GameObject go = new GameObject(nameof(MusicPlayer));
            GameObject.DontDestroyOnLoad(go);
            audioSource = go.AddComponent<AudioSource>();
            audioSource.playOnAwake = false;
            audioSource.loop = false;
            allMusicSources.Add(this);
        }

        public void Update()
        {
            if (canListenPlayEnd)
            {
                if (!audioSource.isPlaying)
                {
                    canListenPlayEnd = false;
                    OnPlayEnd();
                }
            }
        }

        /// <summary>
        /// 播放一个背景音乐
        /// </summary>
        public void Play(AudioClip clip, bool fadeIn = false, float volume = 1, bool loop = true)
        {
            Play(new AudioClip[] { clip }, fadeIn, volume, loop);
        }

        /// <summary>
        /// 播放按一定的排序方法（顺序或随机）播放多个背景音乐
        /// </summary>
        public void Play(AudioClip[] clips, bool fadeIn = false, float volume = 1, bool loop = true, bool randomBegin = false, bool randomNext = false)
        {
            this.clips = clips;
            this.volume = volume;
            this.loop = loop;
            this.randomNext = randomNext;
            float targetVolume = this.volume * Volume;
            if (fadeIn)
            {
                audioSource.volume = 0;
                DOVirtual.Float(0, targetVolume, 5, (float v) =>
                {
                    audioSource.volume = v;
                });
            }
            else
            {
                audioSource.volume = targetVolume;
            }
            this.currClipIndex = randomBegin ? Random.Range(0, clips.Length) : 0;
            AudioClip clip = clips[this.currClipIndex];
            PlayClip(clip);
        }

        private void PlayClip(AudioClip clip)
        {
            audioSource.clip = clip;
            if (IsEnable)
            {
                audioSource.DOKill();
                audioSource.Play();
                canListenPlayEnd = true;
            }
        }

        private void OnEnable(bool enable)
        {
            if (enable)
            {
                if (audioSource.clip)
                {
                    audioSource.DOKill();
                    audioSource.Play();
                    canListenPlayEnd = true;
                }
            }
            else
            {
                if (audioSource.isPlaying)
                {
                    canListenPlayEnd = false;
                    audioSource.Pause();
                }
            }

        }

        private void OnPlayEnd()
        {
            if (loop)
            {
                if (randomNext)
                {
                    currClipIndex = Random.Range(0, clips.Length);
                }
                else
                {
                    currClipIndex++;
                    if (currClipIndex > clips.Length - 1)
                    {
                        currClipIndex = 0;
                    }
                }
                PlayClip(clips[currClipIndex]);
            }
        }

        /// <summary>
        /// 暂停音乐
        /// </summary>
        public void Pause()
        {
            canListenPlayEnd = false;
            audioSource.Pause();
        }

        /// <summary>
        /// 从暂停处回复播放
        /// </summary>
        public void Resume()
        {
            if (IsEnable)
            {
                audioSource.DOKill();
                audioSource.Play();
                canListenPlayEnd = true;
            }
        }

        /// <summary>
        /// 停止播放
        /// </summary>
        public void Stop(bool fadeOut = true)
        {
            canListenPlayEnd = false;
            if (fadeOut)
            {
                audioSource.DOFade(0, 1).OnComplete(() =>
                {
                    audioSource.Stop();
                });
            }
            else
            {
                audioSource.Stop();
            }
        }

        public void OnDestroy()
        {
            if (audioSource)
            {
                allMusicSources.Remove(this);
                GameObject.Destroy(audioSource.gameObject);
            }
        }
    }
}
